package net.suncaper.hotel.service.impl;

import net.suncaper.hotel.common.utils.JDBCUtils;
import net.suncaper.hotel.common.utils.PageInfo;
import net.suncaper.hotel.mapper.*;
import net.suncaper.hotel.mapper.impl.*;
import net.suncaper.hotel.model.domain.*;
import net.suncaper.hotel.model.dto.CheckInDTO;
import net.suncaper.hotel.model.vo.CheckInVO;
import net.suncaper.hotel.service.ICheckInService;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 入住服务实现类
 */
public class CheckInServiceImpl implements ICheckInService {
    private ICheckInMapper checkInMapper = new CheckInMapperImpl();
    private IReservationMapper reservationMapper = new ReservationMapperImpl();
    private ICustomerMapper customerMapper = new CustomerMapperImpl();
    private IRoomMapper roomMapper = new RoomMapperImpl();
    private IRoomTypeMapper roomTypeMapper = new RoomTypeMapperImpl();
    private IUserMapper userMapper = new UserMapperImpl();

    @Override
    public PageInfo<CheckInVO> getCheckInList(int pageNum, int pageSize) {
        PageInfo<CheckInVO> pageInfo = new PageInfo<>(pageNum, pageSize);
        
        // 获取总数
        long total = checkInMapper.count();
        pageInfo.setTotal(total);
        
        // 获取分页数据
        List<CheckIn> checkIns = checkInMapper.findByPage(pageInfo.getStartRow(), pageSize);
        List<CheckInVO> voList = new ArrayList<>();
        if (checkIns != null) {
            for (CheckIn checkIn : checkIns) {
                voList.add(convertToVO(checkIn));
            }
        }
        pageInfo.setList(voList);
        
        return pageInfo;
    }

    @Override
    public PageInfo<CheckInVO> getCurrentGuests(int pageNum, int pageSize) {
        PageInfo<CheckInVO> pageInfo = new PageInfo<>(pageNum, pageSize);
        
        List<CheckIn> checkIns = checkInMapper.findByStatus("CHECKED_IN");
        List<CheckInVO> voList = new ArrayList<>();
        if (checkIns != null) {
            for (CheckIn checkIn : checkIns) {
                voList.add(convertToVO(checkIn));
            }
        }
        
        // 手动分页
        int start = (pageNum - 1) * pageSize;
        int end = Math.min(start + pageSize, voList.size());
        pageInfo.setList(voList.subList(start, end));
        pageInfo.setTotal(voList.size());
        
        return pageInfo;
    }

    @Override
    public CheckInVO getCheckInById(Integer id) {
        if (id == null) {
            return null;
        }
        CheckIn checkIn = checkInMapper.findById(id);
        return convertToVO(checkIn);
    }

    @Override
    public boolean checkInWithReservation(Integer reservationId, Integer operatorId) {
        if (reservationId == null || operatorId == null) {
            return false;
        }
        
        try {
            JDBCUtils.beginTransaction();
            
            // 查询预订信息
            Reservation reservation = reservationMapper.findById(reservationId);
            if (reservation == null || !"CONFIRMED".equals(reservation.getStatus())) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 检查是否已经入住
            CheckIn existCheckIn = checkInMapper.findByReservationId(reservationId);
            if (existCheckIn != null) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 获取房间信息
            Room room = roomMapper.findById(reservation.getRoomId());
            if (room == null || !"AVAILABLE".equals(room.getStatus())) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 创建入住记录
            CheckIn checkIn = new CheckIn();
            checkIn.setReservationId(reservationId);
            checkIn.setCustomerId(reservation.getCustomerId());
            checkIn.setRoomId(reservation.getRoomId());
            checkIn.setCheckInTime(new Date());
            checkIn.setExpectedCheckOutTime(reservation.getCheckOutDate());
            
            // 获取房价
            RoomType roomType = roomTypeMapper.findById(room.getRoomTypeId());
            checkIn.setRoomRate(roomType.getPrice());
            checkIn.setDeposit(reservation.getDeposit());
            checkIn.setStatus("CHECKED_IN");
            checkIn.setOperatorId(operatorId);
            
            // 保存入住记录
            int result = checkInMapper.insert(checkIn);
            if (result <= 0) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 更新预订状态
            reservationMapper.updateStatus(reservationId, "CHECKED_IN");
            
            // 更新房间状态
            roomMapper.updateStatus(room.getId(), "OCCUPIED");
            
            JDBCUtils.commit();
            return true;
            
        } catch (Exception e) {
            e.printStackTrace();
            try {
                JDBCUtils.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            return false;
        } finally {
            JDBCUtils.close();
        }
    }

    @Override
    public boolean checkInWithoutReservation(CheckInDTO dto, Integer operatorId) {
        if (dto == null || operatorId == null) {
            return false;
        }
        
        try {
            JDBCUtils.beginTransaction();
            
            // 处理客户信息
            Integer customerId = dto.getCustomerId();
            if (customerId == null && dto.getCustomerIdNumber() != null) {
                // 新客户，先查询是否已存在
                Customer customer = customerMapper.findByIdNumber(
                    dto.getCustomerIdType() != null ? dto.getCustomerIdType() : "ID_CARD",
                    dto.getCustomerIdNumber()
                );
                
                if (customer == null) {
                    // 创建新客户
                    customer = new Customer();
                    customer.setName(dto.getCustomerName());
                    customer.setIdType(dto.getCustomerIdType() != null ? dto.getCustomerIdType() : "ID_CARD");
                    customer.setIdNumber(dto.getCustomerIdNumber());
                    customer.setPhone(dto.getCustomerPhone());
                    customerMapper.insert(customer);
                    
                    // 重新查询获取ID
                    customer = customerMapper.findByIdNumber(customer.getIdType(), customer.getIdNumber());
                }
                
                customerId = customer.getId();
            }
            
            // 检查房间状态
            Room room = roomMapper.findById(dto.getRoomId());
            if (room == null || !"AVAILABLE".equals(room.getStatus())) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 创建入住记录
            CheckIn checkIn = new CheckIn();
            checkIn.setReservationId(null); // Walk-in客人没有预订
            checkIn.setCustomerId(customerId);
            checkIn.setRoomId(dto.getRoomId());
            checkIn.setCheckInTime(dto.getCheckInTime() != null ? dto.getCheckInTime() : new Date());
            checkIn.setExpectedCheckOutTime(dto.getExpectedCheckOutTime());
            checkIn.setRoomRate(dto.getRoomRate());
            checkIn.setDeposit(dto.getDeposit());
            checkIn.setStatus("CHECKED_IN");
            checkIn.setOperatorId(operatorId);
            checkIn.setNotes(dto.getNotes());
            
            // 保存入住记录
            int result = checkInMapper.insert(checkIn);
            if (result <= 0) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 更新房间状态
            roomMapper.updateStatus(room.getId(), "OCCUPIED");
            
            JDBCUtils.commit();
            return true;
            
        } catch (Exception e) {
            e.printStackTrace();
            try {
                JDBCUtils.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            return false;
        } finally {
            JDBCUtils.close();
        }
    }

    @Override
    public boolean checkOut(Integer id, BigDecimal totalAmount) {
        if (id == null || totalAmount == null) {
            return false;
        }
        
        try {
            JDBCUtils.beginTransaction();
            
            // 查询入住记录
            CheckIn checkIn = checkInMapper.findById(id);
            if (checkIn == null || !"CHECKED_IN".equals(checkIn.getStatus())) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 办理退房
            int result = checkInMapper.checkOut(id, new Date(), totalAmount);
            if (result <= 0) {
                JDBCUtils.rollback();
                return false;
            }
            
            // 更新房间状态为清洁中
            roomMapper.updateStatus(checkIn.getRoomId(), "CLEANING");
            
            // 如果有预订，更新预订状态
            if (checkIn.getReservationId() != null) {
                reservationMapper.updateStatus(checkIn.getReservationId(), "CHECKED_OUT");
            }
            
            JDBCUtils.commit();
            return true;
            
        } catch (Exception e) {
            e.printStackTrace();
            try {
                JDBCUtils.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            return false;
        } finally {
            JDBCUtils.close();
        }
    }

    @Override
    public boolean updateCheckIn(CheckInDTO dto) {
        if (dto == null || dto.getId() == null) {
            return false;
        }
        
        CheckIn checkIn = checkInMapper.findById(dto.getId());
        if (checkIn == null) {
            return false;
        }
        
        checkIn.setExpectedCheckOutTime(dto.getExpectedCheckOutTime());
        checkIn.setRoomRate(dto.getRoomRate());
        checkIn.setDeposit(dto.getDeposit());
        checkIn.setNotes(dto.getNotes());
        
        return checkInMapper.update(checkIn) > 0;
    }

    private CheckInVO convertToVO(CheckIn checkIn) {
        if (checkIn == null) {
            return null;
        }
        
        CheckInVO vo = new CheckInVO();
        vo.setId(checkIn.getId());
        vo.setReservationId(checkIn.getReservationId());
        vo.setCustomerId(checkIn.getCustomerId());
        vo.setRoomId(checkIn.getRoomId());
        vo.setCheckInTime(checkIn.getCheckInTime());
        vo.setExpectedCheckOutTime(checkIn.getExpectedCheckOutTime());
        vo.setActualCheckOutTime(checkIn.getActualCheckOutTime());
        vo.setRoomRate(checkIn.getRoomRate());
        vo.setDeposit(checkIn.getDeposit());
        vo.setTotalAmount(checkIn.getTotalAmount());
        vo.setStatus(checkIn.getStatus());
        vo.setOperatorId(checkIn.getOperatorId());
        vo.setNotes(checkIn.getNotes());
        vo.setCreateTime(checkIn.getCreateTime());
        
        // 获取预订信息
        if (checkIn.getReservationId() != null) {
            Reservation reservation = reservationMapper.findById(checkIn.getReservationId());
            if (reservation != null) {
                vo.setReservationNo(reservation.getReservationNo());
            }
        }
        
        // 获取客户信息
        Customer customer = customerMapper.findById(checkIn.getCustomerId());
        if (customer != null) {
            vo.setCustomerName(customer.getName());
            vo.setCustomerPhone(customer.getPhone());
            vo.setCustomerIdNumber(customer.getIdNumber());
        }
        
        // 获取房间信息
        Room room = roomMapper.findById(checkIn.getRoomId());
        if (room != null) {
            vo.setRoomNumber(room.getRoomNumber());
            RoomType roomType = roomTypeMapper.findById(room.getRoomTypeId());
            if (roomType != null) {
                vo.setRoomTypeName(roomType.getTypeName());
            }
        }
        
        // 获取操作员信息
        if (checkIn.getOperatorId() != null) {
            User operator = userMapper.findById(checkIn.getOperatorId());
            if (operator != null) {
                vo.setOperatorName(operator.getRealName());
            }
        }
        
        // 设置状态文本
        if ("CHECKED_IN".equals(checkIn.getStatus())) {
            vo.setStatusText("在住");
        } else if ("CHECKED_OUT".equals(checkIn.getStatus())) {
            vo.setStatusText("已退房");
        } else {
            vo.setStatusText(checkIn.getStatus());
        }
        
        return vo;
    }
}